<!--------------------------------------------------------------------------->
<!--                           INTRODUCTION

 The Code Project article submission template (HTML version)

Using this template will help us post your article sooner. To use, just
follow the 3 easy steps below:

     1. Fill in the article description details
     2. Add links to your images and downloads
     3. Include the main article text

That's all there is to it! All formatting will be done by our submission
scripts and style sheets.

-->
<!--------------------------------------------------------------------------->
<!--                        IGNORE THIS SECTION                            -->
<html>
<head>
<title>The Code Project</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<Style>
BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }
H2,H3,H4,H5 { color: #ff9900; font-weight: bold; }
H2 { font-size: 13pt; }
H3 { font-size: 12pt; }
H4 { font-size: 10pt; color: black; }
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono;
      WHITE-SPACE: pre; }
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
</style>
</head>
<body bgcolor="#FFFFFF" color=#000000>
<!--------------------------------------------------------------------------->


<!-------------------------------     STEP 1      --------------------------->
<!--  Fill in the details (CodeProject will reformat this section for you) -->

<pre>
Title:       Double buffering in java.awt
Author:      frisco
Email:       sinterklaas@rscafans.be
Environment: JDK 1.0-4, NT 4.0, Win95/98
Keywords:    Java, Awt, Double buffer
Level:       Intermediate"
Description: How to implement the double buffer in standard awt
Section      Java Programming
SubSection   General
</pre>

<hr width=100% noshade>

<!-------------------------------     STEP 2      --------------------------->
<!--  Include download and sample image information.                       -->

<ul class=download>
<li><a href="doublebuffer_src.zip">Download source - 5 Kb</a></li>
</ul>


<!-------------------------------     STEP 3      --------------------------->
<!--  Add the article text. Please use simple formatting (<h2>, <p> etc)   -->

<p>
<h2>INTRODUCTION</h2>
</p>

<p>
Have you ever created an application that showed an animation in your window? You probably have, and if you have not, you probably will someday. The coding is really simple: you take a Panel and you add a thread to it that calls the repaint-method every x milliseconds. Done?<br><br>
</p>

<p>
No, it's not quiet over yet. Because, if you leave it like that, the screen will flash and flicker, and your animation will end up partially painted, or not painted at all.<br><br>
</p>

<p>
The solution for that is the infamous double buffer.<br><br><br>
</p>

<p>
<h2>AWT versus SWING</h2>
</p>

<p>
In the <code>Swing</code> framework, you can add the double buffer just by setting this property to true in your class. <code>Swing</code> is carrying out all of the tasks needed for you. They're behind the scenes, and all that you have to know is that it's done. The flicker is gone. Thank you mister Sun.<br><br>
</p>

<p>
But what if you use the standard awt? The swing framework is rather heavy and still has some nasty bugs, so, on older machines, it's more likely that you use the standard awt. But, there's no double buffer here, isn't it.<br><br>
</p>

<p>
I've studied this problem for some while now, and this is the solution I've come up with. It is a solution, not the solution. I've seen others too, but they all have more or less the same components.<br><br><br>
</p>

<p>
<h2>THE DOUBLEBUFFER-CLASS</h2>
</p>

<p>
Since we are good java-programmers, we create a base-class for this, so we can implement the double buffer functionality whenever we feel like. You can choose between the classes <code>Component</code>, <code>Container</code>, <code>Canvas</code> and <code>Panel</code> to extend, but I suggest you choose the <code>Panel</code> class. If you choose another, you can get problems later on, with some eventlisteners that will not fire properly.<br><br>
</p>

<pre>
import java.awt.*;

public class DoubleBuffer extends Panel{

	public DoubleBuffer(){
		super();
	}
}
</pre>
<br>

<p>
<h2>ELIMINATING THE FLICKER</h2>
</p>

<p>
What's causing the flicker? Well, if you call the repaint-method, you actually tell the vm to repaint this component as soon as possible. You can't tell when (but you can set an initial delay). When the vm has time to carry out the paint tasks, it calls the <code>update</code> method for you. And there's the first problem already. The <code>update</code> method clears the panel for you, so you can paint to it, without concerning about the background. That's what causing the flicker. It clears the panel, shows in the window, paints the panel and shows again. So every paintjob has in fact two jobs, clearing and painting.<br><br>
</p>

<p>
We're going to deprecate this.<br><br>
</p>

<pre>
	public void update(Graphics g){
		paint(g);
	}

	public void paint(Graphics g){
	}
</pre>

<p>
Now, the background isn't cleared anymore, so the flicker is gone. If you use this to animate through some images with the same dimensions, you are finished here already, because you don't have to clear the previous image.<br><br>
</p>

</p>
But what if you have to clear the previous paintjob?<br><br><br>
</p>

<p>
<h2>THE BUFFER IMAGE</h2>
</p>

<p>
The idea behind double buffering is that you first paint everything to an offscreen image, and, when it's ready, paint it to the screen in just one paintjob. For this purpose, we need a bufferimage and it's brother buffergraphics. This image has always the same dimensions as your panel, so if your panel resizes, the image has to resize also, and the previous has to be cleared out of memory.<br><br>
</p>

<pre>
	//	class variables
	private int bufferWidth;
	private int bufferHeight;
	private Image bufferImage;
	private Graphics bufferGraphics;

	public void paint(Graphics g){
		//	checks the buffersize with the current panelsize
		//	or initialises the image with the first paint
		if(bufferWidth!=getSize().width || bufferHeight!=getSize().height || bufferImage==null || bufferGraphics==null)
			resetBuffer();
	}

	private void resetBuffer(){
		// always keep track of the image size
		bufferWidth=getSize().width;
		bufferHeight=getSize().height;

		//	clean up the previous image
		if(bufferGraphics!=null){
			bufferGraphics.dispose();
			bufferGraphics=null;
		}
		if(bufferImage!=null){
			bufferImage.flush();
			bufferImage=null;
		}
		System.gc();

		//	create the new image with the size of the panel
		bufferImage=createImage(bufferWidth,bufferHeight);
		bufferGraphics=bufferImage.getGraphics();
	}
</pre>

<p>
So, your bufferimage has been created and now it's ready to picasso. We add some functionality to the <code>paint</code> method and create a <code>paintbuffer</code> method. After that the offscreen image has to be copied to the screen. Everything is painted on the screen in one go, so bye bye flicker.<br><br>
</p>

<pre>
	public void paint(Graphics g){
		...	resetBuffer();

		if(bufferGraphics!=null){
			//	this clears the offscreen image, not the onscreen one
			bufferGraphics.clearRect(0,0,bufferWidth,bufferHeight);

			//	calls the paintbuffer method with the offscreen graphics as a param
			paintBuffer(bufferGraphics);

			//	we finaly paint the offscreen image onto the onscreen image
			g.drawImage(bufferImage,0,0,this);
		}
	}

	public void paintBuffer(Graphics g){
		//	in classes extended from this one, add something to paint here!
		//	always remember, g is the offscreen graphics
	}
</pre>

<p>
Now, your double buffer class is ready!<br><br><br>
</p>

<p>
<h2>EXTENDING THE NEW CLASS</h2>
</p>

<p>
Now, everything you have to do is to extend <code>DoubleBuffer</code> and deprecate the <code>paintBuffer</code> method instead of the <code>paint</code> method. In your application, you can call the <code>repaint</code> method whenever you feel like, and the screen is not going to flicker once.<br><br>
</p>

<pre>
public class MyBuffer extends DoubleBuffer{

	private int posX;

	public MyBuffer(){
		super();

		posX=0;
	}

	public void animateToTheRight(){
		//	this can be called from everywhere, anytime
		posX++;
		repaint();
	}

	//	attention: we don't touch update() and paint() anymore
	//	we use paintbuffer() instead

	public void paintBuffer(Graphics g){
		/// g is the offscreen graphics
		g.drawString("Double Buffer!",posX,20);
	}
}
</pre>

<p>
In the example, if you add a thread and let it call <code>animateToTheRight()</code>, a string is scrolling from left to right, without causing any flicker.<br><br>
</p>

<p>
Voila, the double buffer is working.<br><br><br>
</p>




<!-------------------------------    That's it!   --------------------------->
</body>
</html>
